package com.panfeng.xcloud.boss.provider.assets.service.exchange.impl;

import com.alibaba.fastjson.JSONObject;
import com.binance.client.model.enums.CandlestickInterval;
import com.panfeng.xcloud.boss.provider.assets.service.exchange.IExchangeOperateService;
import com.panfeng.xcloud.boss.provider.dto.request.OperateBotReqDTO;
import com.panfeng.xcloud.common.core.enums.ExchangeTypeEnum;
import com.panfeng.xcloud.common.core.enums.ResponseStatusEnum;
import com.panfeng.xcloud.common.core.exceptions.BaseBizException;
import com.panfeng.xcloud.common.core.web.vo.InnerTransferVO;
import com.panfeng.xcloud.common.core.web.vo.OrderDetailResponseVO;
import com.panfeng.xcloud.common.core.web.vo.TradeResponseVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;

@Service
@Slf4j
public class ExchangeOperateServiceImpl implements IExchangeOperateService {

    @Autowired
    private OkexMethodService okexMethodService;

    @Autowired
    private HuobiMethodService huobiMethodService;

    @Autowired
    private BinanceMethodService binanceMethodService;

    /**
     * 查询账户总可用余额
     *
     * @param exchangeType
     * @param userId
     * @param valuationAsset
     * @return
     */
    @Override
    public BigDecimal getTotalAvaliableMoney(Integer exchangeType, String userId, String valuationAsset) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getTotalAvaliableMoney(userId, valuationAsset);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getTotalAvaliableMoney(userId, valuationAsset);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getTotalAvaliableMoney(userId, valuationAsset);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 查询某交易对保证金率
     *
     * @param exchangeType
     * @param userId
     * @param contractCode
     * @param direction
     * @return
     */
    @Override
    public BigDecimal getRiskRate(Integer exchangeType, String userId, String contractCode, String direction) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getRiskRate(userId, contractCode, direction);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getRiskRate(userId, contractCode, direction);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getRiskRate(userId, contractCode, direction);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 查询某交易对的可用仓位
     *
     * @param exchangeType
     * @param userId
     * @param contractCode
     * @param direction
     * @param leverRate
     * @return
     */
    @Override
    public BigDecimal getAvaliablePosition(Integer exchangeType, String userId, String contractCode, String direction, Integer leverRate) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getAvaliablePosition(userId, contractCode, direction, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getAvaliablePosition(userId, contractCode, direction, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getAvaliablePosition(userId, contractCode, direction, leverRate);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 查询某交易对的开仓均价
     *
     * @param exchangeType
     * @param userId
     * @param contractCode
     * @param direction
     * @param leverRate
     * @return
     */
    @Override
    public BigDecimal getPositionAgvPrice(Integer exchangeType, String userId, String contractCode, String direction, Integer leverRate) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getPositionAgvPrice(userId, contractCode, direction, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getPositionAgvPrice(userId, contractCode, direction, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getPositionAgvPrice(userId, contractCode, direction, leverRate);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 查询某交易对的可用余额
     *
     * @param exchangeType
     * @param userId
     * @param contractCode
     * @return
     */
    @Override
    public BigDecimal getAvaliableMoney(Integer exchangeType, String userId, String contractCode) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getAvaliableMoney(userId, contractCode);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getAvaliableMoney(userId, contractCode);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getAvaliableMoney(userId, contractCode);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 查询某交易对的可开数
     *
     * @param exchangeType
     * @param userId
     * @param destinationCoin
     * @param sourceCoin
     * @param direction
     * @param leverRate
     * @return
     */
    @Override
    public BigDecimal getAvaliablePieces(Integer exchangeType, String userId, String destinationCoin, String sourceCoin, String direction, Integer leverRate) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getAvaliablePieces(userId, destinationCoin, sourceCoin, direction, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getAvaliablePieces(userId, destinationCoin, sourceCoin, direction, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getAvaliablePieces(userId, destinationCoin, sourceCoin, direction, leverRate);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 交易所下市价单
     *
     * @param exchangeType
     * @param operateBotReqDTO
     * @return
     */
    @Override
    public TradeResponseVO trade(Integer exchangeType, OperateBotReqDTO operateBotReqDTO) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.trade(operateBotReqDTO);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.trade(operateBotReqDTO);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.trade(operateBotReqDTO);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 获取订单详情
     *
     * @param exchangeType
     * @param operateBotReqDTO
     * @param tradeResponseVO
     * @return
     */
    @Override
    public OrderDetailResponseVO getOrderDetail(Integer exchangeType, OperateBotReqDTO operateBotReqDTO, TradeResponseVO tradeResponseVO) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getOrderDetail(operateBotReqDTO, tradeResponseVO);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getOrderDetail(operateBotReqDTO, tradeResponseVO);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getOrderDetail(operateBotReqDTO, tradeResponseVO);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 同账户内资金划转
     *
     * @param exchangeType
     * @param innerTransferVO
     * @return
     */
    @Override
    public String transferInner(Integer exchangeType, InnerTransferVO innerTransferVO) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.transferInner(innerTransferVO);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.transferInner(innerTransferVO);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.transferInner(innerTransferVO);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 获取展示市价
     *
     * @param exchangeType
     * @param userId
     * @param destinationCoin
     * @param sourceCoin
     * @return
     */
    @Override
    public BigDecimal getAppearMarketPrice(Integer exchangeType, String userId, String destinationCoin, String sourceCoin) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getAppearMarketPrice(userId, destinationCoin, sourceCoin);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getAppearMarketPrice(userId, destinationCoin, sourceCoin);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getAppearMarketPrice(userId, destinationCoin, sourceCoin);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 获取行情深度,供计算使用
     *
     * @param exchangeType
     * @param userId
     * @param destinationCoin
     * @param sourceCoin
     * @return
     */
    @Override
    public JSONObject getMarketPriceDepth(Integer exchangeType, String userId, String destinationCoin, String sourceCoin) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getMarketPriceDepth(userId, destinationCoin, sourceCoin);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getMarketPriceDepth(userId, destinationCoin, sourceCoin);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getMarketPriceDepth(userId, destinationCoin, sourceCoin);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 判断杠杆倍数是否可用
     *
     * @param exchangeType
     * @param userId
     * @param destinationCoin
     * @param sourceCoin
     * @param leverRate
     * @return
     */
    @Override
    public boolean leverRateCanUse(Integer exchangeType, String userId, String destinationCoin, String sourceCoin, Integer leverRate) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.leverRateCanUse(userId, destinationCoin, sourceCoin, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.leverRateCanUse(userId, destinationCoin, sourceCoin, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.leverRateCanUse(userId, destinationCoin, sourceCoin, leverRate);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 调用接口调整杠杆倍数
     *
     * @param exchangeType
     * @param userId
     * @param destinationCoin
     * @param sourceCoin
     * @param leverRate
     * @return
     */
    @Override
    public boolean changeLeverRate(Integer exchangeType, String userId, String destinationCoin, String sourceCoin, Integer leverRate) {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.changeLeverRate(userId, destinationCoin, sourceCoin, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.changeLeverRate(userId, destinationCoin, sourceCoin, leverRate);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.changeLeverRate(userId, destinationCoin, sourceCoin, leverRate);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

    /**
     * 获取K线数据
     *
     * @param exchangeType
     * @param userId
     * @param destinationCoin
     * @param sourceCoin
     * @param interval
     * @param startTime
     * @param endTime
     * @param limit
     * @return
     */
    @Override
    public JSONObject getCandleStick(Integer exchangeType, String userId, String destinationCoin, String sourceCoin, CandlestickInterval interval, Long startTime, Long endTime, int limit) throws InterruptedException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        if (exchangeType == ExchangeTypeEnum.OKEX.getCode()) {
            return okexMethodService.getCandleStick(exchangeType, userId, destinationCoin, sourceCoin, interval, startTime, endTime, limit);
        } else if (exchangeType == ExchangeTypeEnum.HUOBI.getCode()) {
            return huobiMethodService.getCandleStick(exchangeType, userId, destinationCoin, sourceCoin, interval, startTime, endTime, limit);
        } else if (exchangeType == ExchangeTypeEnum.BINANCE.getCode()) {
            return binanceMethodService.getCandleStick(exchangeType, userId, destinationCoin, sourceCoin, interval, startTime, endTime, limit);
        } else {
            throw new BaseBizException(ResponseStatusEnum.EXCHANGE_TYPE_NOT_EXIST);
        }
    }

}
